//*************************************************************************\\
//***********               tdc_automata.h      		***********\\
//*************************************************************************\\
//*************************************************************************\\
//*********** 		        UFPE/Cin - Greco		***********\\
//*********** 		 http://www.cin.ufpe.br/~greco 		***********\\
//***********							***********\\
//***********							***********\\
//*********** 		    By Rafael Melo Macieira		***********\\
//***********							***********\\
//***********		    E-mail: rmm2@cin.ufpe.br		***********\\
//*************************************************************************\\
//*************************************************************************\\
//**		 Automata Reference for the temporal check		 **\\
//**	   	 VIRTUAL CLASS                                           **\\
//*************************************************************************\\

#ifndef TDC_AUTOMATA_H
#define TDC_AUTOMATA_H

class TDC_Automata;
class VarList;
class AutomataList;

class AutomataList {
private:
    unsigned int platformAddr;
    TDC_Automata *automata;
    AutomataList *nextAutomata;
    int EOL;
    

public:
    AutomataList(unsigned int platformAddr, TDC_Automata* automata);
    void addNextAutomata(AutomataList *automataList);
    AutomataList* getNextAutomata();
    TDC_Automata* getAutomata();
    void setAutomata(TDC_Automata *automata);
    unsigned int getPlatformAddr();
    bool isEOL();
    AutomataList* getAutomataListByPlatformAddr(AutomataList* mainAutomataList, unsigned int platformAddr);
    bool contains(AutomataList* mainAutomataList, unsigned int platformAddr);
};

class VarList {
private:
    unsigned int platformAddr;
    unsigned int *var;
    VarList *nextVar;
    int EOL;


public:
    VarList(unsigned int platformAddr, unsigned int *var);
    void addNextVar(VarList *varList);
    VarList* getNextVar();
    unsigned int* getVar();
    void setVar(unsigned int *var);
    unsigned int getPlatformAddr();
    bool isEOL();
    VarList* getVarListByPlatformAddr(VarList* mainVarList, unsigned int platformAddr);
    bool contains(VarList* mainVarList, unsigned int platformAddr);
};

class TDC_Automata {
 private:

  enum StateID {A,R};  

  virtual void printRejection(StateID stateID);

  virtual int checkState(StateID stateID);

  virtual int checkInitialState();

  virtual StateID getNextState(StateID stateID);

  virtual void refreshVariables(VarList* currentVarList);


 public:

  virtual int runStep(bool access_type, VarList* currentVarList);

  virtual void reset();

  unsigned int *lcd_ctrl_reg;
  //char *lcd_var_cmd;
  bool access_type;
  char* name;

  TDC_Automata(char* name);

};

#define GET_REG_DATA_CMD(value)			((value & 0x100) && 0x100)
#define GET_REG_CMD(value)				(value)

#endif
